package com.tqjc.system.core.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.tqjc.system.common.constant.AddTaskConstant;
import com.tqjc.system.common.constant.ConfigConstant;
import com.tqjc.system.common.constant.GlobalConstant;
import com.tqjc.system.common.constant.RemoteURLConstant;
import com.tqjc.system.common.entity.BO.PLCWriteRequestParamBO;
import com.tqjc.system.common.entity.BO.ResponseLabelDataBO;
import com.tqjc.system.common.enums.AlarmStatusEnum;
import com.tqjc.system.common.enums.CarMonitorDotInfoEnum;
import com.tqjc.system.core.pipeline.thread.AbstrCarDoingAddTaskThread;
import com.tqjc.system.core.util.PLCHttpsUtils;
import com.tqjc.system.core.util.SpringUtils;
import com.tqjc.system.core.websocket.TaskExecutionWebSocketService;
import com.tqjc.system.system.entity.SysAlarmInfoEntity;
import com.tqjc.system.system.service.SysAlarmInfoService;
import com.tqjc.system.system.util.SystemUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @description:
 * @Author: 86195
 * @Date: 2024/1/4 9:15
 **/
@Component
@Slf4j
public class MonitorCarStatusTask {

    @Autowired
    private SysAlarmInfoService alarmInfoService;

    @Autowired
    private TaskExecutionWebSocketService taskExecutionWebSocketService;

    private Map<String, String> snMap = SystemUtils.Sys_carInfo.get(ConfigConstant.CONFIG_TYPE_CAR_BAK_SN);

    //每5秒执行一次
    @Scheduled(cron = "0/5 * * * * ? ")
    public void monitor(){
        String errMsg;
        boolean flag = false;
        for (CarMonitorDotInfoEnum value : CarMonitorDotInfoEnum.values()) {
            //单车总点位异常标识
            boolean allFlag = false;
            //获取天车sn
            String carName = value.getCarName();
            String sn = snMap.get(carName);
            Map map = new HashMap(2);
            map.put(GlobalConstant.STRING_SN,sn);
            for (Object[] info : value.getDotLableInfo()) {
                //object[] info 标签值  正常值
                int i = 0;
                //每次复原
                flag = false;
                errMsg = null;
                String lable = (String) info[0];
                map.put(GlobalConstant.STRING_LABEL, carName + lable);
                //遍历读取每一个监控点位值
                while (true){
                    if(i >= 3){
                        errMsg = lable ;
                        log.error("天车：{}，点位：{},重复读取三次",carName,lable);
                        break;
                    }
                    i++;

                    try {
                        ResponseLabelDataBO responseLabelDataBO = PLCHttpsUtils.sendPost(RemoteURLConstant.URL_READBC, map, ResponseLabelDataBO.class);
                        Map<String, String> content = responseLabelDataBO.getContent();
                        if(content != null){
                            boolean res = Boolean.valueOf(content.get(GlobalConstant.STRING_CURRENTVAL));
                            flag = Objects.equals(res,info[1]);
                            if(flag){
                                break;
                            }
                        }

                        Thread.sleep(5*1000);
                    } catch (Exception e){
                        log.error("告警监控点位信息任务运行异常",e);
                    }
                }

                if(!flag){
                    //点位异常
                    allFlag = true;
                    //1.记录日志
                    saveFaultInfo(carName,errMsg,lable);
                    //2.翻转对应线程的状态
                    AbstrCarDoingAddTaskThread myselfThread = AddTaskConstant.CAR_THREAD_MAP.get(carName);
                    AbstrCarDoingAddTaskThread otherThread = AddTaskConstant.CAR_THREAD_MAP.get(value.getOtherCarName());
                    if(myselfThread != null){
                        log.error("天车:{},出现异常,异常信息为:{}",carName,errMsg);
                        myselfThread.setTaskFlag(true);
                    }
                    if(otherThread != null){
                        log.error("天车:{},出现异常,异常信息为:{}",carName,errMsg);
                        otherThread.setTaskFlag(true);
                    }
                }
            }

            if(allFlag && !GlobalConstant.VISIT_MODEL_FLAG){
                //单台车出现异常  且参观模式未开
                PLCWriteRequestParamBO plcWriteRequestParamBO = PLCWriteRequestParamBO.builder().label(carName + GlobalConstant.LABEL_TASK_PAUSE)
                        .macSN(carName).dataType(0).address(value.getTaskPauseAddress()).value("true").build();
                try {
                    PLCHttpsUtils.write(RemoteURLConstant.URL_WRITEBC,plcWriteRequestParamBO);
                    Map msgMap = new HashMap(1);
                    msgMap.put("code","30");
                    msgMap.put("data",carName);
                    taskExecutionWebSocketService.sendMessage(msgMap);
                } catch (Exception e){
                    log.error("天车:{},定时监控天车点位状态出现异常，写值任务暂停点位失败,异常信息为:{}",carName,e);
                }

            }

            if(!allFlag){
                //单台车没有异常，翻转当前车以往的异常为已完成
                log.info("{}：此刻没有异常，翻转正常的状态");
                //查看当前天车是否存在异常
                int count = alarmInfoService.count(new LambdaQueryWrapper<SysAlarmInfoEntity>().eq(SysAlarmInfoEntity::getCarName, carName)
                        .eq(SysAlarmInfoEntity::getStatus, AlarmStatusEnum.ALARM_STATUS_INIT.getStatus())
                        .ge(SysAlarmInfoEntity::getCreateDate, LocalDateTime.now().minusDays(3)));
                if(count > 0){
                    alarmInfoService.update(new LambdaUpdateWrapper<SysAlarmInfoEntity>().eq(SysAlarmInfoEntity::getCarName,carName)
                            .eq(SysAlarmInfoEntity::getStatus,AlarmStatusEnum.ALARM_STATUS_INIT.getStatus())
                            .set(SysAlarmInfoEntity::getUpdateDate,LocalDateTime.now())
                            .set(SysAlarmInfoEntity::getStatus, AlarmStatusEnum.ALARM_STATUS_DONE.getStatus())
                            .ge(SysAlarmInfoEntity::getCreateDate, LocalDateTime.now().minusDays(3)));
                }


            }

        }

    }


    private void saveFaultInfo(String carName,String errMsg,String type){
        //判断近一周内该异常信息是否已出现且未处理   是则需要插入数据
        int count = alarmInfoService.isNewAlarmInfo(carName,type);
        if(count <= 0){
            SysAlarmInfoEntity alarmInfoEntity = SysAlarmInfoEntity.builder().type(type).carName(carName).type(type).errMsg(errMsg).build();
            try {
                alarmInfoService.save(alarmInfoEntity);
            } catch (Exception e){
                log.error("出现异常",e);
            }
            Map map = new HashMap(1);
            map.put("code","10");
            taskExecutionWebSocketService.sendMessage(map);
        }
    }




}
